package com.eunion.core;

import java.io.BufferedOutputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.hssf.usermodel.HSSFFont;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.hssf.util.HSSFColor;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.ss.util.CellRangeAddress;
import org.apache.poi.xssf.usermodel.XSSFCellStyle;
import org.apache.poi.xssf.usermodel.XSSFFont;

import com.eunion.common.util.CommUtils;
import com.eunion.common.util.RegUtils;
import com.eunion.web.cms.entity.Major;
import com.eunion.web.cms.entity.MajorRecruitPlan;
import com.eunion.web.cms.entity.RecruitStudentsPlan;
import com.eunion.web.cms.entity.ScoreControllerLine;
import com.eunion.web.cms.entity.ScoreRank;
import com.eunion.web.cms.entity.University;
import com.eunion.web.cms.entity.UniversitySetMajor;

public class ExcelUtil {

    /**
     * 判断字符串是否为专业分类
     * 
     * @param str
     * @return
     */
    private static boolean isMajorType(String str) {
        if (StringUtils.isNotBlank(str) && (str.contains("（") || str.contains("("))) {
            return true;
        }
        return false;
    }

    private static String getMajorTypeCode(String str) {
        String[] strs = str.split("（");
        return strs[1].replace("）", "");
    }

    private static String getMajorTypeName(String str) {
        String[] strs = str.split("（");
        return strs[0];
    }

    private static String getMajorCode(String majorClassCode, int order) {
        String str = (order < 10) ? "0" + order : "" + order;
        return majorClassCode + str;
    }

    /**
     * 按列读取表格数据
     */
    public static List<Major> readMajorByColumn(Sheet sheet) {
        // 得到行数
        int totalRows = sheet.getPhysicalNumberOfRows();
        // 得到列数
        int totalColumns = 0;
        if (totalRows >= 1 && sheet.getRow(0) != null) {
            totalColumns = sheet.getRow(0).getPhysicalNumberOfCells();
        }

        Cell cell = null;
        String cellStr = "";
        // 解析出来的总条数
        long totalMajorNum = 0;
        List<Major> majorList = new ArrayList<>();
        for (int lie = 0; lie < totalColumns; lie++) {
            // 专业一级分类
            String majorSubject = "";
            String majorSubjectCode = "";

            // 专业二级分类
            String majorClassCode = "";
            String majorClass = "";

            // 记录专业在二级分类下的顺序
            int order = 1;
            for (int r = 0; r < totalRows; r++) {
                cell = sheet.getRow(r).getCell(lie);
                if (cell == null) {
                    // 单元格为空，退出第二层循环，进入下一列。
                    break;
                }

                cellStr = cell.getStringCellValue().trim();
                // 第一行表示专业的一级分类。
                if (r == 0) {
                    majorSubject = getMajorTypeName(cellStr);
                    majorSubjectCode = getMajorTypeCode(cellStr);
                } else {
                    // 专业二级分类
                    if (isMajorType(cellStr)) {
                        majorClassCode = getMajorTypeCode(cellStr);
                        majorClass = getMajorTypeName(cellStr);
                        // 重置序号
                        order = 1;
                    } else {
                        totalMajorNum += 1;
                        // 具体专业
                        majorList
                        .add(new Major(getMajorCode(majorClassCode, order), cellStr,majorSubjectCode, majorSubject,majorClassCode, majorClass));
                        order += 1;
                    }
                }
            }
        }
        // System.out.println(totalMajorNum);
        return majorList;
    }

    public static Major readMajorAbortInfos(Row row) {

        Major major = new Major();
        Cell cell = row.getCell(0);
        if(cell != null) 
            major.setMajorCode(cell.getStringCellValue());
        cell = row.getCell(1);
        if(cell != null) 
            major.setLearnYear(cell.getStringCellValue());
        cell = row.getCell(2);
        if(cell != null)
            major.setMajorInfo(cell.getStringCellValue());
        cell = row.getCell(3);
        if(cell != null)
            major.setRaiseRequire(cell.getStringCellValue());
        cell = row.getCell(4);
        if(cell != null)
            major.setMainCourse(cell.getStringCellValue());
        cell = row.getCell(7);
        if(cell != null)
            major.setKnowledgeCapacity(cell.getStringCellValue());
        cell = row.getCell(8);
        if(cell != null)
            major.setRaiseGoal(cell.getStringCellValue());

        cell = row.getCell(9);
        if(cell != null)
            major.setAwardDegree(cell.getStringCellValue());
        return major;

    }

    /**
     * 读取大学数据
     * 表头：学校代码，院校代码，简称，中文名，英文名，外文名，国家重点学科，学校地址，地址，院系设置，学校类型，类型，
     *     校训，学校官网，校庆日，现任领导，博士后，博士，硕士，校徽，创办时间，类别，属性，知名校友
     * @param sheet
     */
    public static List<University> readUniversity(Sheet sheet) {
        // 得到行数
        int totalRows = sheet.getPhysicalNumberOfRows();

        // 解析出来的总条数
        List<University> list = new ArrayList<>();
        University cur = null;
        Row row = null;
        // 第1行是表头，从第2行开始是数据，下标为1。
        for (int i = 1; i < totalRows; i++) {
            row = sheet.getRow(i);
            cur = getUniversityByRow(row);
            if (cur != null) {
                list.add(cur);
            }
        }
        return list;
    }

    /**
     * 表头：学校代码，院校代码，简称，中文名，英文名，外文名，国家重点学科，学校地址，地址，院系设置，学校类型，类型，
     *     校训，学校官网，校庆日，现任领导，博士后，博士，硕士，校徽，创办时间，类别，属性，知名校友
     */
    private static University getUniversityByRow(Row row) {
        Map<String, String> map = new HashMap<>();
        Cell cell = null;
        // 存在空行
        if (row == null) {
            return null;
        }
        // 如果学校名称为空，也认为该行数据无效。
        cell = row.getCell(3);
        if (cell == null) {
            return null;
        } else {
            map.put("name", cell.getStringCellValue().trim());
        }

        // 学校代码
        cell = row.getCell(0);
        if (cell == null) {
            cell = row.getCell(1);
            if (cell != null) {
                map.put("code", RegUtils.getNumbers(cell.getStringCellValue()));
            }
        } else {
            map.put("code", RegUtils.getNumbers(cell.getStringCellValue()));
        }

        // 简称
        cell = row.getCell(2);
        if (cell != null) {
            map.put("shortName", cell.getStringCellValue().trim());
        }

        // 英文名
        cell = row.getCell(4);
        if (cell == null) {
            cell = row.getCell(5);
            if (cell != null) {
                map.put("enName", cell.getStringCellValue().trim());
            }
        } else {
            map.put("enName", cell.getStringCellValue().trim());
        }

        // 国家重点学科
        cell = row.getCell(6);
        if (cell != null) {
            map.put("importSubject", cell.getStringCellValue().trim());
        }

        // 学校地址
        cell = row.getCell(7);
        if (cell == null) {
            cell = row.getCell(8);
            if (cell != null) {
                map.put("address", cell.getStringCellValue().trim());
            }
        } else {
            map.put("address", cell.getStringCellValue().trim());
        }

        // 院系设置
        cell = row.getCell(9);
        if (cell != null) {
            map.put("collegeSet", cell.getStringCellValue().trim());
        }

        // 学校类型
        cell = row.getCell(10);
        if (cell == null) {
            cell = row.getCell(11);
            if (cell != null) {
                map.put("type", cell.getStringCellValue().trim());
            }
        } else {
            map.put("type", cell.getStringCellValue().trim());
        }

        // 校训
        cell = row.getCell(12);
        if (cell != null) {
            map.put("motto", cell.getStringCellValue().trim());
        }

        // 学校官网
        cell = row.getCell(13);
        if (cell != null) {
            map.put("website", cell.getStringCellValue().trim());
        }

        // 校庆日
        cell = row.getCell(14);
        if (cell != null) {
            map.put("anniversary", cell.getStringCellValue().trim());
        }

        // 现任领导
        cell = row.getCell(15);
        if (cell != null) {
            map.put("leader", cell.getStringCellValue().trim());
        }

        // 博士后
        cell = row.getCell(16);
        if (cell != null) {
            map.put("bohouPoints", RegUtils.getNumbers(cell.getStringCellValue()));
        }

        // 博士
        cell = row.getCell(17);
        if (cell != null) {
            map.put("boPoints", RegUtils.getNumbers(cell.getStringCellValue()));
        }

        // 硕士
        cell = row.getCell(18);
        if (cell != null) {
            map.put("shuoPoints", RegUtils.getNumbers(cell.getStringCellValue()));
        }

        // 校徽
        cell = row.getCell(19);
        if (cell != null) {
            map.put("logoUrl", cell.getStringCellValue().trim());
        }

        // 创办年份
        cell = row.getCell(20);
        if (cell != null) {
            map.put("creation", RegUtils.getNumbers(cell.getStringCellValue()));
        }

        // 办学性质，公办、民办
        cell = row.getCell(21);
        if (cell != null) {
            map.put("classify", cell.getStringCellValue().trim());
        }

        // 学校标签，211,985,双一流等
        cell = row.getCell(22);
        if (cell != null) {
            map.put("tags", cell.getStringCellValue().trim());
        }

        // 知名校友
        cell = row.getCell(23);
        if (cell != null) {
            map.put("classmate", cell.getStringCellValue().trim());
        }
        return University.getFromMap(map);
    }

    /**
     * 读取学校开设专业数据
     * 表头：学校名称、专业名称、专业代码、专业排名
     * @param sheet
     * @return
     */
    public static List<UniversitySetMajor> readUniversityMajor(Sheet sheet) {
        // 得到行数
        int totalRows = sheet.getPhysicalNumberOfRows();
        List<UniversitySetMajor> list = new ArrayList<>();
        UniversitySetMajor cur = null;
        Row row = null;

        String universityName = "";
        String majorCode = "";
        String majorName = "";
        int rank = 0;
        // 第1行是表头，从第2行开始是数据，下标为1。
        for (int i = 1; i < totalRows; i++) {
            row = sheet.getRow(i);
            // 对数据进行校验
            if (row == null || row.getCell(0) == null || row.getCell(1) == null || row.getCell(2) == null) {
                continue;
            }

            // 专业代码都是6位数，以此来校验。
            if (row.getCell(2).getStringCellValue().length() == 6) {
                universityName = row.getCell(0).getStringCellValue().trim();
                majorName = row.getCell(1).getStringCellValue().trim();
                majorCode = row.getCell(2).getStringCellValue().trim();
                if (row.getCell(3) != null) {
                    rank = Integer.parseInt(row.getCell(3).getStringCellValue());
                }

                cur = new UniversitySetMajor(universityName, majorCode, majorName, rank);
                list.add(cur);
            }
        }

        return list;
    }

    /**
     * 读取某年某个省份的分数段统计表数据。
     * 表头：分数，累计考生人数
     * 如：2018年_河南省_普通高招分数段统计表(理科).xlsx
     * 注意文件名的格式。
     * @param sheet
     */
    public static List<ScoreRank> readScoreRankData(Sheet sheet, String fileName) {
        // 方向，1.文科，2.理科
        int direction = 0;
        if (StringUtils.isNotBlank(fileName)) {
            if (fileName.contains("文科")) {
                direction= 1;
            } else if (fileName.contains("理科")) {
                direction= 2;
            } else {
                return null;
            }
        } else {
            return null;
        }

        // 年份
        String year = RegUtils.getNumbers(fileName);
        // 省份
        String provinceName = fileName.split("_")[1].replace("省", "");

        // 得到行数
        int totalRows = sheet.getPhysicalNumberOfRows();
        List<ScoreRank> list = new ArrayList<>();
        Row row = null;

        int score = 0;
        // 存放前一个总人数，用于计算位次。
        int preTotalPerson = 0;
        int totalPerson = 0;
        String rank = "";

        // 第1行是表头，从第2行开始是数据，下标为1。
        for (int i = 1; i < totalRows; i++) {
            row = sheet.getRow(i);
            // 对数据进行校验
            if (row == null || row.getCell(0) == null || row.getCell(1) == null) {
                continue;
            }

            if (isNumericType(row.getCell(0))) {
                score = (int)row.getCell(0).getNumericCellValue();
            } else {
                score = Integer.parseInt(row.getCell(0).getStringCellValue().trim());
            }

            if (isNumericType(row.getCell(1))) {
                totalPerson = (int)row.getCell(1).getNumericCellValue();
            } else {
                totalPerson = Integer.parseInt(row.getCell(1).getStringCellValue().trim());
            }
            // 计算位次信息
            if (preTotalPerson + 1 < totalPerson) {
                rank = (preTotalPerson + 1) + "-" + totalPerson;
            } else {
                // 否则相等
                rank = totalPerson + "";
            }
            // 赋值
            preTotalPerson = totalPerson;
            // 构建对象并添加进去。
            list.add(new ScoreRank(year, provinceName, direction, score, totalPerson, rank));
        }
        return list;
    }

    /**
     * 读取某个省份的招生计划数据
     * 表头：院校代码，院校名称，计划，实际投档人数，投档最低分
     * 如：2018年_河南省_理科一本分数线.xlsx
     * 注意文件名的格式。
     * @param sheet
     * @param fileName
     * @param scoreRankMap 分数对应的排名范围
     * @return
     */
    public static List<RecruitStudentsPlan> readRecruitPlan(Sheet sheet, String fileName, Map<String, String> scoreRankMap) {
        // 方向，1.文科，2.理科
        int direction = 0;
        if (StringUtils.isNotBlank(fileName)) {
            if (fileName.contains("文科")) {
                direction= 1;
            } else if (fileName.contains("理科")) {
                direction= 2;
            } else {
                return null;
            }
        } else {
            return null;
        }

        // 年份
        String year = RegUtils.getNumbers(fileName);
        // 省份
        String provinceName = fileName.split("_")[1].replace("省", "");

        // 批次，1.一本，2.二本，3.三本  4:大专 
        int batch = 0;
        if (fileName.contains("一")) {
            batch = 1;
        } else if (fileName.contains("二")) {
            batch = 2;
        } else if (fileName.contains("三")) {
            batch = 3;
        } else if (fileName.contains("专")) {
            batch = 4;
        }

        // 得到行数
        int totalRows = sheet.getPhysicalNumberOfRows();
        List<RecruitStudentsPlan> list = new ArrayList<>();
        Row row = null;

        Map<String, String> map = null;
        // 第1行是表头，从第2行开始是数据，下标为1。
        for (int i = 1; i < totalRows; i++) {
            row = sheet.getRow(i);
            // 对数据进行校验
            if (row == null || row.getCell(0) == null) {
                continue;
            }
            map = new HashMap<>();
            map.put("year", year);
            map.put("provinceName", provinceName);
            map.put("direction", direction + "");
            map.put("batch", batch + "");

            if (isNumericType(row.getCell(0))) {
                map.put("collegeCode", (int)row.getCell(0).getNumericCellValue() + "");
            } else {
                map.put("collegeCode", row.getCell(0).getStringCellValue().trim());
            }

            map.put("collegeName", row.getCell(1).getStringCellValue().trim());

            if (isNumericType(row.getCell(2))) {
                map.put("planNum", (int)row.getCell(2).getNumericCellValue() + "");
            } else {
                map.put("planNum", row.getCell(2).getStringCellValue().trim());
            }

            if (isNumericType(row.getCell(3))) {
                map.put("actualNum", (int)row.getCell(3).getNumericCellValue() + "");
            } else {
                map.put("actualNum", row.getCell(3).getStringCellValue().trim());
            }

            if (isNumericType(row.getCell(4))) {
                map.put("lowestScore", (int)row.getCell(4).getNumericCellValue() + "");
            } else {
                map.put("lowestScore", row.getCell(4).getStringCellValue().trim());
            }

            // 得到分数对应的排名范围
            map.put("rank", scoreRankMap.get(map.get("lowestScore")));

            list.add(RecruitStudentsPlan.getFromMap(map));
        }
        return list;
    }

    public static List<ScoreControllerLine> readScoreControllerLine(Sheet sheet){
        List<ScoreControllerLine> list = new ArrayList<>();
        // 得到行数
        int totalRows = sheet.getPhysicalNumberOfRows();

        Row row = null;

        Map<String, String> map = null;
        // 第1行是表头，从第2行开始是数据，下标为1。
        for (int i = 1; i < totalRows; i++) {
            row = sheet.getRow(i);
            // 对数据进行校验
            if (row == null || row.getCell(0) == null) {
                continue;
            }
            map = new HashMap<>();
            if (isNumericType(row.getCell(0))) {
                map.put("year", (int)row.getCell(0).getNumericCellValue() + "");
            } else {
                map.put("year", row.getCell(0).getStringCellValue().trim());
            }

            map.put("provinceName", row.getCell(1).getStringCellValue().trim());
            map.put("direction", row.getCell(2).getStringCellValue().trim());
            map.put("batch", row.getCell(3).getStringCellValue().trim());
            if (isNumericType(row.getCell(4))) {
                map.put("lowestScore", (int)row.getCell(4).getNumericCellValue() + "");
            } else {
                map.put("lowestScore", row.getCell(4).getStringCellValue().trim());
            }

            list.add(ScoreControllerLine.getFromMap(map));
        }
        return list;
    }


    public static List<MajorRecruitPlan> readMajorRecruitPlan(Sheet sheet,String fileName){
        // 方向，1.文科，2.理科
        int direction = 0;
        if (StringUtils.isNotBlank(fileName)) {
            if (fileName.contains("文科")) {
                direction= 1;
            } else if (fileName.contains("理科")) {
                direction= 2;
            } else {
                return null;
            }
        } else {
            return null;
        }

        // 年份
        String year = RegUtils.getNumbers(fileName);
        // 省份
        String provinceName = fileName.split("_")[1].replace("省", "");

        // 批次，1.一本，2.二本，3.三本
        int batch = 0;
        if (fileName.contains("一")) {
            batch = 1;
        } else if (fileName.contains("二")) {
            batch = 2;
        } else if (fileName.contains("三")) {
            batch = 3;
        } else if (fileName.contains("专科")) {
            batch = 4;
        }

        // 得到行数
        int totalRows = sheet.getPhysicalNumberOfRows();
        List<MajorRecruitPlan> list = new ArrayList<>();
        Row row = null;

        Map<String, String> map = null;
        // 第1行是表头，从第2行开始是数据，下标为1。
        String collegeCode = "";
        String collegeName = "";
        for (int i = 1; i < totalRows; i++) {
            
            row = sheet.getRow(i);
            // 对数据进行校验
            if (row == null) {
                continue;
            }

            map = new HashMap<>();
            map.put("year", year);
            map.put("provinceName", provinceName);
            map.put("direction", direction + "");
            map.put("batch", batch + "");
            String tempCollegeCode = "";
            Cell cell = row.getCell(0);
            if(cell != null ) {
                if (isNumericType(cell)) {
                    tempCollegeCode = (int)cell.getNumericCellValue() + "";
                    //map.put("collegeCode", (int)row.getCell(0).getNumericCellValue() + "");
                } else {
                    tempCollegeCode = cell.getStringCellValue().trim();
                    //map.put("collegeCode", row.getCell(0).getStringCellValue().trim());
                }
            }
            if(!CommUtils.isEmpty(tempCollegeCode)) {
                collegeCode = tempCollegeCode;
                String tempCollegeName = "";
                cell = row.getCell(1);
                if(cell != null) {
                    tempCollegeName = row.getCell(1).getStringCellValue().trim();
                }

                if(!CommUtils.isEmpty(tempCollegeName)) {
                    collegeName = tempCollegeName;
                }
            }
            map.put("collegeCode", collegeCode);
            map.put("collegeName", collegeName.split(" ")[0]);
            //专业代码
            String tempMajorCode = "";
            cell = row.getCell(3);
            if(cell != null) {
                if (isNumericType(cell)) {
                    tempMajorCode =  (int)cell.getNumericCellValue() + "";
                } else {
                    tempMajorCode = cell.getStringCellValue().trim();
                }
            }

            if(!CommUtils.isEmpty(tempMajorCode)) {
                map.put("majorCode", tempMajorCode);
            } else {
                continue;
            }

            //System.err.println("majorCode:" + tempMajorCode);
            //专业名称
            String tempMajorName = "";
            cell = row.getCell(4);
            if(cell != null) {
                if (isNumericType(cell)) {
                    tempMajorName = (int)cell.getNumericCellValue() + "";
                    //map.put("lowestScore", (int)row.getCell(4).getNumericCellValue() + "");
                } else {
                    tempMajorName = cell.getStringCellValue().trim();
                    //map.put("lowestScore", row.getCell(4).getStringCellValue().trim());
                }
            }
            // System.err.println("tempMajorName:" + tempMajorName);
            if(!CommUtils.isEmpty(tempMajorName)) {
                String regexPlanNum = "\\d{1,}人";

                String majorName = "";
                String planNum = "";
                String remark = "";
                String planNumReg = "";
                if (tempMajorName.contains("(") && tempMajorName.contains(")")) {
                    majorName = tempMajorName.substring(0,tempMajorName.indexOf("("));
                    planNumReg =  RegUtils.getFirstMatcher(tempMajorName,regexPlanNum);
                    planNum = planNumReg.replace("人", "");
                    if (StringUtils.isBlank(planNumReg)) {
                        remark = tempMajorName;
                    } else {
                        //System.err.println("collegeCode:" + collegeCode+";tempMajorName:" + tempMajorName );
                        remark = tempMajorName.substring(tempMajorName.indexOf("("),tempMajorName.lastIndexOf(")")+1);
                    }
                    // System.err.println("majorName:" + majorName + ";planNum:" + planNum + ";remark:" + remark);
                } else {
                    planNumReg =  RegUtils.getFirstMatcher(tempMajorName,regexPlanNum);
                    planNum = planNumReg.replace("人", "");
                    if (StringUtils.isBlank(planNumReg)) {
                        remark = tempMajorName;
                    } else {
                        majorName = tempMajorName.substring(0,tempMajorName.lastIndexOf(planNumReg));
                    }
                }
                map.put("majorName", majorName);
                map.put("planNum", planNum);
                map.put("remark", remark);
            }
            list.add(MajorRecruitPlan.getFromMap(map));
        }
        return list;
    }


    /**
     * 检查是否为数字类型的单元格
     * @param cell
     * @return
     */
    private static boolean isNumericType(Cell cell) {
        if(cell == null) {
            return false;
        }
        if (Cell.CELL_TYPE_NUMERIC == cell.getCellType()) {
            return true;
        }
        return false;
    }

    private static CellStyle createHeadCellStyle(Workbook workbook, int excelType, short align) {
        CellStyle style = null;

        if (excelType == 1) {
            // 生成一个07样式
            style = (XSSFCellStyle) workbook.createCellStyle();

            // 生成一个字体
            XSSFFont font = (XSSFFont) workbook.createFont();
            font.setFontHeightInPoints((short) 12);
            font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);// 设置粗体
            font.setFontName("宋体");

            style.setFont(font);
            // 设置背景颜色为灰色
            style.setFillPattern(CellStyle.SOLID_FOREGROUND);
            style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);

            style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
            style.setBorderRight(XSSFCellStyle.BORDER_THIN);
            style.setBorderTop(XSSFCellStyle.BORDER_THIN);
            style.setAlignment(align);
            style.setWrapText(true);// 设置自动换行
        } else {
            // 生成一个03样式
            style = (HSSFCellStyle) workbook.createCellStyle();

            // 生成一个字体
            HSSFFont font = (HSSFFont) workbook.createFont();
            font.setFontHeightInPoints((short) 12);
            font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);// 设置粗体
            font.setFontName("宋体");
            style.setFont(font);

            // 设置背景颜色为灰色
            style.setFillPattern(CellStyle.SOLID_FOREGROUND);
            style.setFillForegroundColor(HSSFColor.GREY_25_PERCENT.index);

            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            style.setAlignment(align);
            style.setWrapText(true);
        }

        return style;
    }

    private static CellStyle createNormalCellStyle(Workbook workbook, int excelType, short align) {
        CellStyle style = null;

        if (excelType == 1) {
            // 生成一个07样式
            style = (XSSFCellStyle) workbook.createCellStyle();

            style.setBorderBottom(XSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(XSSFCellStyle.BORDER_THIN);
            style.setBorderRight(XSSFCellStyle.BORDER_THIN);
            style.setBorderTop(XSSFCellStyle.BORDER_THIN);
            // 1:左对齐 2:居中 3:右对齐
            style.setAlignment(align);
            // style.setVerticalAlignment(XSSFCellStyle.ALIGN_CENTER);
            style.setWrapText(true);// 设置自动换行
            // 生成一个字体
            XSSFFont font = (XSSFFont) workbook.createFont();
            font.setFontHeightInPoints((short) 12);
            // font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);//设置粗体
            style.setFont(font);
        } else {
            // 生成一个03样式
            style = (HSSFCellStyle) workbook.createCellStyle();

            style.setBorderBottom(HSSFCellStyle.BORDER_THIN);
            style.setBorderLeft(HSSFCellStyle.BORDER_THIN);
            style.setBorderRight(HSSFCellStyle.BORDER_THIN);
            style.setBorderTop(HSSFCellStyle.BORDER_THIN);
            // 1:左对齐 2:居中 3:右对齐
            style.setAlignment(align);
            // style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);
            style.setWrapText(true);
            // 生成一个字体
            HSSFFont font = (HSSFFont) workbook.createFont();
            font.setFontHeightInPoints((short) 12);
            // font.setBoldweight(HSSFFont.BOLDWEIGHT_BOLD);//设置粗体
            style.setFont(font);
        }

        return style;
    }

    /**
     * 判断给定的 k 是否在 cols 中
     * 
     * @param k
     * @param cols
     * @return
     */
    public static boolean isInArray(int k, int[] cols) {
        boolean flag = false;
        if (null != cols && cols.length > 0) {
            for (int i = 0; i < cols.length; i++) {
                if (k == cols[i]) {
                    flag = true;
                    break;
                }
            }
        }

        return flag;
    }

    /**
     * 在[min, max]范围内获取size个随机整数。
     * 
     * @param min
     *            最小值（包含）
     * @param max
     *            最大值（包含）
     * @param size
     *            个数
     * @return 升序排列后返回
     */
    public static int[] getRandomIntArray(int min, int max, int size) {
        if (size > (max - min + 1) || max < min) {
            return null;
        }

        // 标记最小值min是否为0，true:0，false:非0
        boolean zeroFlag = false;
        if (min == 0) {
            // 当min=0时，变向处理：min、max都加1
            zeroFlag = true;
            min += 1;
            max += 1;
        }

        Random random = new Random();
        // 默认值为0
        int[] result = new int[size];
        int count = 0;

        while (count < size) {
            /*
             * 1.当min=0时，s的范围在[0, max-1]; 2.当min>0时，s的范围在[min, max];
             */
            int s = random.nextInt(max) % (max - min + 1) + min;
            /*
             * 当s=0时（min=0时，s才可能等于0），isInArray(s, result) 为 true 此时0不会被添加到result中
             */
            if (!isInArray(s, result)) {
                result[count] = s;
                count++;
            }
        }

        if (zeroFlag) {
            for (int i = 0; i < size; i++) {
                result[i] = result[i] - 1;
            }
        }

        // 对数组进行升序排列
        Arrays.sort(result);
        return result;
    }

    /**
     * 导出报表到输出流中
     * 
     * @param fileOut
     *            输入流
     * @param sheetName
     *            名称
     * @param headers
     *            表格头部
     * @param data
     *            数据
     * @throws Exception
     */
    public static void createExcel(HttpServletResponse response, String sheetName, List<String> headers,
            List<List<String>> data) throws Exception {
        OutputStream fileOut = new BufferedOutputStream(response.getOutputStream());
        Workbook workbook = null;
        workbook = new HSSFWorkbook();
        Sheet sheet = workbook.createSheet(sheetName);
        // 设置表格默认列宽度为20个字节
        sheet.setDefaultColumnWidth(20);
        // 设置行高，以像素为单位，一个像素15.625
        sheet.setDefaultRowHeight((short) 400);

        // 表头样式
        CellStyle headStyle = createHeadCellStyle(workbook, 0, XSSFCellStyle.ALIGN_CENTER);

        Row row = null;
        Cell cell = null;
        Cell cell1 = null;
        if (headers != null) {
            row = sheet.createRow(0);
            Row row1 = sheet.createRow(1);
            for (int i = 0; i < headers.size(); i++) {
                cell = row.createCell(i);

                // 合并单元格 开始行，结束行，开始列，结束列 都包含
                CellRangeAddress region = new CellRangeAddress(0, 1, i, i); // 参数都是从O开始
                sheet.addMergedRegion(region);
                cell.setCellValue(headers.get(i));
                headStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
                cell.setCellStyle(headStyle);
                cell1 = row1.createCell(i);
                cell1.setCellStyle(headStyle);
            }
        }
        if (data != null && data.size() > 0) {
            for (int i = 0; i < data.size(); i++) {
                row = sheet.createRow(i + 2);
                List<String> rowDataList = data.get(i);
                for (int j = 0; j < rowDataList.size(); j++) {
                    String colValue = rowDataList.get(j);
                    cell = row.createCell(j);
                    cell.setCellValue(colValue);
                }
            }
        }
        workbook.write(fileOut);
        fileOut.close();
    }
    //
    // /**
    // * 导出明细账表格 导出科目表 导出财务期初余额表 导出项目核算明细账(币别类型为：STD 本位币、RMB 人民币)
    // *
    // * @param fileOut
    // * @param sheetMap
    // * @param headers
    // * @param sheetName
    // * @throws Exception
    // */
    // public static void createMxzExcel(OutputStream fileOut, Map<Integer, List<String>> sheetMap, String[] headers,
    // String sheetName, int[] cols)
    // throws Exception {
    // // Excel文件初始化
    // Workbook workbook = null;
    // workbook = new HSSFWorkbook();
    // Sheet sheet = workbook.createSheet(sheetName);
    //
    // // 设置表格默认列宽度为20个字节
    // sheet.setDefaultColumnWidth(20);
    // // 设置行高，以像素为单位，一个像素15.625
    // sheet.setDefaultRowHeight((short) 400);
    //
    // // 表头样式
    // CellStyle headStyle = createHeadCellStyle(workbook, 0, XSSFCellStyle.ALIGN_CENTER);
    //
    // // 单元格样式
    // CellStyle curCellStyle = null;
    //
    // Row row = null;
    // Cell cell = null;
    // Cell cell1 = null;
    // List<String> curRow = null;
    // if (null != headers) {
    // row = sheet.createRow(0);
    // Row row1 = sheet.createRow(1);
    // for (int i = 0; i < headers.length; i++ ) {
    // cell = row.createCell(i);
    //
    // // 合并单元格 开始行，结束行，开始列，结束列 都包含
    // CellRangeAddress region = new CellRangeAddress(0, 1, i, i); // 参数都是从O开始
    // sheet.addMergedRegion(region);
    // cell.setCellValue(headers[i]);
    // headStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
    // cell.setCellStyle(headStyle);
    //
    // cell1 = row1.createCell(i);
    // cell1.setCellStyle(headStyle);
    // }
    // }
    //
    // if (null != sheetMap && sheetMap.size() > 0) {
    //
    // for (int j = 0; j < sheetMap.size(); j++ ) {
    // // 表头占了2行，所以要加2
    // row = sheet.createRow(j + 2);
    // curRow = sheetMap.get(j);
    // for (int k = 0; k < headers.length; k++ ) {
    // // 当前行row得第k列的单元格对象
    // cell = row.createCell(k);
    // // 文本右对齐的列
    // if (isInArray(k, cols)) {
    // curCellStyle = createNormalCellStyle(workbook, 0, XSSFCellStyle.ALIGN_RIGHT);
    // } else {
    // curCellStyle = createNormalCellStyle(workbook, 0, XSSFCellStyle.ALIGN_LEFT);
    // }
    // cell.setCellStyle(curCellStyle);
    // // 为单元格对象设置对应的值
    // cell.setCellValue(curRow.get(k));
    // }
    //
    // }
    //
    // } else {
    // throw new Exception("表格数据不能为空！");
    // }
    //
    // workbook.write(fileOut);
    // fileOut.close();
    // }

}
